﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using mVu.Properties;

namespace mVu
{
  public partial class DownloadItem : UserControl
  {
    public DownloadItem()
    {
      InitializeComponent();

      IsDownloading = false;

      cancelButton.Enabled = false;
      cancelButton.Image = Resources.CancelDisabled;
      pauseButton.Enabled = true;
      pauseButton.Image = Resources.PlayEnabled;
    }

    public string FileName { get; set; }
    public string URL { get; set; }
    public int Index { get; set; }
    public bool IsDownloading { get; set; }
    public bool IsPaused { get; set; }

    public void Start()
    {
      cancelButton.Enabled = true;
      cancelButton.Image = Resources.CancelEnabled;
      pauseButton.Enabled = true;
      pauseButton.Image = Resources.PauseEnabled;

      fileLabel.Text = FileName;

      var dl = new DownloadThread {Url = URL, Filename = FileName, Item = this};
      dl.CompleteCallback += DownloadCompleteCallback;
      dl.ProgressCallback += DownloadProgressCallback;

      var t = new Thread(dl.Download);
      t.Start();

      IsDownloading = true;
      IsPaused = false;
    }

    public void Stop()
    {
      IsDownloading = false;
    }

    private void DownloadProgressCallback(DownloadInfo info)
    {
      this.InvokeIfRequired(() =>
      {
        progressBar1.Value = info.BytesProcessed < info.DataLength ? Convert.ToInt32(Convert.ToDouble(info.BytesProcessed) / info.DataLength * 100.0 % 100) : 100;

        var ts = DateTime.Now - info.StartTime;

        if (info.DataLength <= (1024 * 1024))
        {
          progressLabel.Text = String.Format("{0:0}kB of {1:0}kB ({2:0}kB/sec)", info.BytesProcessed / 1024.0, info.DataLength / 1024.0, (info.BytesProcessed - info.StartPoint) / ts.TotalSeconds / 1024.0);
        }
        else
        {
          progressLabel.Text = String.Format("{0:0.0}MB of {1:0.0}MB ({2:0}kB/sec)", info.BytesProcessed / 1024.0 / 1024.0, info.DataLength / 1024.0 / 1024.0, (info.BytesProcessed - info.StartPoint) / ts.TotalSeconds / 1024.0);
        }
      });
    }

    private void DownloadCompleteCallback(string fileName)
    {
      try
      {
        if (IsPaused)
        {
          this.InvokeIfRequired(() => { progressLabel.Text = "Paused"; });
        }
        else if (IsDownloading)
        {
#if PocketPC
          this.InvokeIfRequired(() =>
                                  {
                                    var notification = new Microsoft.WindowsCE.Forms.Notification();
                                    notification.Text = String.Format("Download complete.\n\n{0}", fileLabel.Text);
                                    notification.Caption = "mVu";
                                    notification.BalloonChanged +=
                                      delegate(object s, Microsoft.WindowsCE.Forms.BalloonChangedEventArgs args)
                                        {
                                          if (args.Visible == false)
                                          {
                                            notification.Dispose();
                                          }
                                        };
                                    notification.Visible = true;
                                  });
#else
          MessageBox.Show(String.Format("Download complete.\n\n{0}", fileLabel.Text), Resources.AppName, MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
#endif
          this.InvokeIfRequired(() =>
          {
            progressLabel.Text = "Complete";
            cancelButton.Enabled = false;
            cancelButton.Image = Resources.CancelDisabled;
            pauseButton.Enabled = false;
            pauseButton.Image = Resources.PauseDisabled;
          });

          IsDownloading = false;
        }
        else
        {
          this.InvokeIfRequired(() =>
                                  {
                                    var result = MessageBox.Show(String.Format("Download cancelled.\n\nWould you like to delete \"{0}\"?", fileLabel.Text), Resources.AppName, MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);

                                    if (result == DialogResult.Yes)
                                    {
                                      File.Delete(fileName);
                                    }

                                    progressLabel.Text = "Cancelled";
                                    cancelButton.Enabled = false;
                                    cancelButton.Image = Resources.CancelDisabled;
                                    pauseButton.Enabled = false;
                                    pauseButton.Image = Resources.PauseDisabled;
                                  });

        }
      }
      catch (Exception ex)
      {
        Utilities.HandleError(ex);
      }
    }

    private void PauseButtonClick(object sender, EventArgs e)
    {
      try
      {
        if (!IsPaused)
        {
          this.InvokeIfRequired(() =>
          {
            IsPaused = true;
            pauseButton.Image = Resources.PlayEnabled;
            cancelButton.Image = Resources.CancelDisabled;
          });
        }
        else
        {
          // Resume
          this.InvokeIfRequired(() => { fileLabel.Text = FileName; });

          var dl = new DownloadThread
                     {
                       Url = URL,
                       Filename = FileName,
                       Item = this
                     };

          dl.CompleteCallback += DownloadCompleteCallback;
          dl.ProgressCallback += DownloadProgressCallback;

          var t = new Thread(dl.Download);
          t.Start();

          IsDownloading = true;
          IsPaused = false;

          this.InvokeIfRequired(() =>
          {
            pauseButton.Image = Resources.PauseEnabled;
            cancelButton.Image = Resources.CancelEnabled;
          });
        }
      }
      catch (Exception ex)
      {
        Utilities.HandleError(ex);
      }
    }

    private void CancelButtonClick(object sender, EventArgs e)
    {
      try
      {
        this.InvokeIfRequired(() => { IsDownloading = false; });
      }
      catch (Exception ex)
      {
        Utilities.HandleError(ex);
      }
    }
  }
}